#!/usr/bin/perl -w
use strict;

chomp(my $hostname = $ENV{HTTP_HOST} || `hostname`);
chomp(my $pwd = `pwd`);

my $rollout_url = "https://$hostname/rollout/";
my $component_path = "$pwd/components";

my %sub = (
    BASE_URL => $rollout_url,
    STEPS => join(",", map "'$_'",
	grep s/^\Q$component_path\E\///, # always true
	sort <$component_path/*.pl>),
);

(my $body = do { local $/ = undef; <DATA> })
    =~ s!__([A-Z_]+?)__!$sub{$1}||"__$1__"!ge;

print "Content-Type: text/plain\n\n"
    if $ENV{GATEWAY_INTERFACE};

print $body;

__DATA__
#!/usr/bin/perl -w
use strict;

BEGIN {
    use IO::Socket;

    sub Rollout::_connect
    {
	my ($addr, $port, $ssl) = @_;

	return IO::Socket::INET->new("$addr:$port")
	    unless $ssl;

	socketpair(my $parent, my $child, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
	    or die;

	$parent->autoflush(1);
	$child->autoflush(1);

	if (!fork)
	{
	    close $parent;

	    open STDIN, "<&", $child or die "dup STDIN: $!";
	    open STDOUT, ">&", $child or die "dup STDOUT: $!";
	    open STDERR, ">>/dev/null" or die "open STDERR: $!";
	    exec "openssl", "s_client", "-quiet", "-connect", "$addr:$port";
	    die "exec openssl: $!";
	}

	close $child;

	return $parent;
    }

    sub Rollout::_open_http
    {
	my $url = shift;

	my ($proto, $addr, $port, $path) = $url =~ m|^(https?)://([^:/]+)(?::([^/]+))?(.*)|
	    or return;
	$port ||= ($proto eq 'https' ? 443 : 80);
	my $sock = Rollout::_connect($addr, $port, $proto eq 'https')
	    or return;
	print $sock "GET $path HTTP/1.0\n\n";
	local $_;
	($_ = <$sock> || "") =~ m|^HTTP/1\.[01] 200 .*|
	    or return;
	1 while ($_ = <$sock>) =~ m|\S|;
	return $sock;
    }

    # include from network
    push @INC, sub {
	my ($self, $filename) = @_;

	return Rollout::_open_http($filename =~ m|^https?://| ? $filename : "__BASE_URL__/$filename");
    };
};

use Rollout qw(:all);

my $rollout_lock = exclusive_lock
    or die "Aborted: already running\n";

$Rollout::log_fd = \*STDOUT;

our %m;
our $domain;
our $ROLLOUT = '__BASE_URL__';
require "$ROLLOUT/conf/rollout.cfg";

chomp(our $hostname = `hostname`);
$hostname =~ s/\.$domain$//;

{
    no strict 'refs';

    foreach my $func (qw(in_class add_class fetch_val fetch_all fetchall_hash fetchall_array))
    {
	*$func = sub { return &{"Rollout::$func"}(\%m, $hostname, @_); };
    }

    foreach my $func (qw(classes type_list))
    {
	*$func = sub { return &{"Rollout::$func"}(\%m, @_); };
    }
}

my @steps = (__STEPS__);

foreach (@steps)
{
    my ($name, $os) = /^(?:\d+\-)?(.*?)(?:\.(\w+))?\.pl$/
	or die "Bad X\n";
    $os ||= $^O;
    next unless $os eq $^O;

    my $code = slurp_file("$ROLLOUT/components/$_")
	or die "Couldn't read file: $ROLLOUT/components/$_\n";

    print "Running: $name\n";
    eval $code;
    die $@ if $@;
}
